package com.heima.ThreadPool.CountDownLatch;

import com.heima.Main;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: Ethan Yankang
 * @Program: 面试必会代码
 * @Date: 2024-08-29 16:51
 **/
/*
 * 首先明确CountDownLatch作用————CountDownLatch是一个同步辅助类，用于在多线程下协调线程的执行顺序，
 * 通常让一个或多个线程等待其他线程完成一些操作。他可以在线程池中很有效的协调任务执行。
 *
 * 核心原理————
* 使用方法
创建 CountDownLatch：

CountDownLatch 在创建时需要指定一个计数器，该计数器表示需要等待的线程数量或任务数量。

* 倒计时操作：

当一个线程完成了它的任务后，可以通过调用 countDown() 方法将计数器减 1。

* 等待操作：

主线程或其他需要等待的线程可以调用 await() 方法，阻塞当前线程，直到计数器变为 0。
 *
 * 重要方法————
 * 1.await()用来等待技术归零
 * 2.countDown() 用来让计数减一
 *
 */



    /*
     * @description 这个实例是用来说明CountDownLatch可以让自定义的线程池任务执行完毕后，主线程再执行之【也就是主线程等待所有子线程执行完毕后在执行主线程的任务】
     * @params
     * @return
     */

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {

        final int taskNums=10;// 定义任务数量
        CountDownLatch countDownLatch = new CountDownLatch(taskNums);//定义一个CountDownCount，计数器初始化为任务数量
        ExecutorService es = Executors.newFixedThreadPool(3);//创建一个固定大小的线程池
        for (int i = 0; i < taskNums; i++) {
            final int taskId = i;
            es.submit(() -> {
                try {
                    System.out.println("Task " + taskId + " is been processing by" + Thread.currentThread().getName());
                    // 模拟线程执行时间
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
            System.out.println("这是在await()之前执行的，线程穿插执行");
            countDownLatch.await();
            System.out.println("这是在await()之后执行的，线程等待计数器结束后执行的");
            System.out.println("All Tasks Completed");
            es.shutdown();

    }
}
